import { RouteRecordRaw } from 'vue-router'
const modules = import.meta.glob('../../views/**/**.vue')
import { constantRoutes } from '@/router'
const Layout = () => import('../../layout/index.vue')
import MenuAPI from '@/api/menu'
import { RouteVO } from '@/api/menu/model'
import { store } from '@/store'
/**
 * Use meta.role to determine if the current user has permission
 *
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
    if (route.meta && route.meta.roles) {
        // 角色【超级管理员】拥有所有权限，忽略校验
        if (roles.includes('ROOT')) {
            return true
        }
        return roles.some((role) => {
            if (route.meta?.roles) {
                return route.meta.roles.includes(role)
            }
        })
    }
    return false
}
/**
 * 递归过滤有权限的动态路由
 *
 * @param routes 接口返回所有的动态路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的动态路由
 */
const filterAsyncRoutes = (routes: RouteVO[], roles: string[]) => {
    const asyncRoutes: RouteRecordRaw[] = []
    routes.forEach((route) => {
        const tmpRoute = { ...route } as RouteRecordRaw // 深拷贝 route 对象 避免污染
        if (hasPermission(roles, tmpRoute)) {
            // 如果是顶级目录，替换为 Layout 组件
            if (tmpRoute.component?.toString() == 'Layout') {
                tmpRoute.component = Layout
            } else {
                // 如果是子目录，动态加载组件
                const component =
                    modules[`../../views/${tmpRoute.component}.vue`]
                if (component) {
                    tmpRoute.component = component
                } else {
                    tmpRoute.component =
                        modules[`../../views/error-page/404.vue`]
                }
            }

            if (tmpRoute.children) {
                tmpRoute.children = filterAsyncRoutes(route.children, roles)
            }

            asyncRoutes.push(tmpRoute)
        }
    })

    return asyncRoutes
}
// setup
export const usePermissionStore = defineStore('permission', () => {
    // state
    const routes = ref<RouteRecordRaw[]>([])
    const mixLeftMenus = ref<RouteRecordRaw[]>([])
    // actions
    function setRoutes(newRoutes: RouteRecordRaw[]) {
        routes.value = constantRoutes.concat(newRoutes)
    }
    /**
     * 生成动态路由
     *
     * @param roles 用户角色集合
     * @returns
     */
    function generateRoutes(roles: string[]) {
        return new Promise<RouteRecordRaw[]>((resolve, reject) => {
            // 接口获取所有路由
            MenuAPI.getRoutes()
                .then((data) => {
                    // 过滤有权限的动态路由
                    const accessedRoutes = filterAsyncRoutes(data, roles)
                    setRoutes(accessedRoutes)
                    resolve(accessedRoutes)
                })
                .catch((error) => {
                    reject(error)
                })
        })
    }
    /**
     * 获取与激活的顶部菜单项相关的混合模式左侧菜单集合
     */

    function setMixLeftMenus(topMenuPath: string) {
        const matchedItem = routes.value.find(
            (item) => item.path === topMenuPath
        )
        if (matchedItem && matchedItem.children) {
            mixLeftMenus.value = matchedItem.children
        }
    }
    return {
        routes,
        setRoutes,
        generateRoutes,
        mixLeftMenus,
        setMixLeftMenus,
    }
})
// 非setup
export function usePermissionStoreHook() {
    return usePermissionStore(store)
}
